﻿namespace ShellNavigator.Client.Controls
{
  #region

  using System;
  using System.Windows;
  using System.Windows.Controls;
  using System.Windows.Input;
  using System.Windows.Shapes;
  using System.Windows.Threading;

  #endregion

  /// <summary>
  ///     A circular type progress bar, that is simliar to popular web based
  ///     progress bars
  /// </summary>
  public partial class CircularProgressBar
  {
    #region Constants and Fields

    private readonly DispatcherTimer animationTimer;

    #endregion

    #region Constructors and Destructors

    public CircularProgressBar()
    {
      this.InitializeComponent();

      this.animationTimer = new DispatcherTimer(DispatcherPriority.ContextIdle, this.Dispatcher);
      this.animationTimer.Interval = new TimeSpan(0, 0, 0, 0, 75);
    }

    #endregion

    #region Methods

    private void HandleAnimationTick(object sender, EventArgs e)
    {
      this.SpinnerRotate.Angle = (this.SpinnerRotate.Angle + 36) % 360;
    }

    private void HandleLoaded(object sender, RoutedEventArgs e)
    {
      const double step = Math.PI * 2 / 10.0;
      const double offset = Math.PI;

      var ellipses = new[] { this.C0, this.C1, this.C2, this.C3, this.C4, this.C5, this.C6, this.C7, this.C8 };

      for (var i = 0; i < ellipses.Length; i++)
      {
        this.SetValue(ellipses[i], offset, step, i);
      }
    }

    private void HandleUnloaded(object sender, RoutedEventArgs e)
    {
      this.Stop();
    }

    private void HandleVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
    {
      bool isVisible = (bool)e.NewValue;

      if (isVisible)
      {
        this.Start();
      }
      else
      {
        this.Stop();
      }
    }

    private void SetValue(Ellipse ellipse, double offset, double step, double shift)
    {
      ellipse.SetValue(Canvas.LeftProperty, 50.0 + Math.Sin(offset + shift * step) * 50.0);
      ellipse.SetValue(Canvas.TopProperty, 50 + Math.Cos(offset + shift * step) * 50.0);
    }

    private void Start()
    {
      Mouse.OverrideCursor = Cursors.Wait;
      this.animationTimer.Tick += this.HandleAnimationTick;
      this.animationTimer.Start();
    }

    private void Stop()
    {
      this.animationTimer.Stop();
      Mouse.OverrideCursor = Cursors.Arrow;
      this.animationTimer.Tick -= this.HandleAnimationTick;
    }

    #endregion
  }
}